/*
 * Created on 2005-3-12
 */
package com.hd123.rumba.user;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import net.sf.hibernate.Session;
import net.sf.hibernate.Transaction;
import net.sf.hibernate.cfg.Configuration;
import net.sf.hibernate.cfg.Environment;

import com.hd123.rumba.domain.IDomain;
import com.hd123.rumba.domain.IDomainMgr;
import com.hd123.rumba.runtime.HibernateSession;
import com.hd123.rumba.runtime.NamingMgr;
import com.hd123.rumba.runtime.OperateContext;
import com.hd123.rumba.util.StringUtil;

/**
 * @author caili
 */
public class UserTest {

  public static void main(String[] args) throws Exception {
    UserTest s = new UserTest();
    s.createSchema();
    s.createData();
    // s.removePermission("perm2");
    // s.removeRole("role1");
    // s.removePermissionFromRole("perm1", "role3");
    // s.removeUser("user1");
    // s.removeRoleFromUser("role2", "user2");
    // s.removePermissionFromUser("perm1", "user2");
    // s.hasPermission("user3", "perm3");
    // s.hasPermission("user2", "perm3");
    // s.grantPermission("user3", "user2", "perm3");
    // s.hasPermission("user2", "perm3");
    // s.revokePermission("user3", "user2", "perm3");
    // s.hasPermission("user2", "perm3");
  }

  public void displayAllPermRoleUser(String s) throws Exception {
    println("*********************************");
    println("* All perm role user " + s);
    println("*********************************");
    displayAllPermissions();
    displayAllRoles();
    displayAllUsers();
  }

  public void displayAllPermissions() throws Exception {
    IPermissionMgr permMgr = (IPermissionMgr) NamingMgr.getInstance().lookupMgr(
        IPermissionMgr.class);
    List list = permMgr.createAllPermissionsList();
    println("All permissions:");
    for (int i = 0; i < list.size(); ++i) {
      IPermission perm = (IPermission) list.get(i);
      println("  " + perm.getCode());
    }
  }

  public void displayAllRoles() throws Exception {
    IRoleMgr roleMgr = (IRoleMgr) NamingMgr.getInstance().lookupMgr(IRoleMgr.class);
    List list = roleMgr.createAllRolesList(((IDomainMgr) NamingMgr.getInstance().lookupMgr(
        IDomainMgr.class)).getRootDomain());
    println("All roles:");
    for (int i = 0; i < list.size(); ++i) {
      IRole role = (IRole) list.get(i);
      println("  " + role.getCode());
      displayRolePermissions(role);
      displayRoleUsers(role);
    }
  }

  private void displayRolePermissions(IRole role) throws Exception {
    println("  " + role.getCode() + " has following permissions:");
    List list = ((IRoleMgr) NamingMgr.getInstance().lookupMgr(IRoleMgr.class))
        .createPermissionsList(role);
    for (int i = 0; i < list.size(); ++i) {
      IPermission perm = (IPermission) list.get(i);
      println("    " + perm.getCode());
    }
  }

  private void displayRoleUsers(IRole role) throws Exception {
    println("  " + role.getCode() + " has following users:");
    List list = ((IRoleMgr) NamingMgr.getInstance().lookupMgr(IRoleMgr.class))
        .createUsersList(role);
    for (int i = 0; i < list.size(); ++i) {
      IUser user = (IUser) list.get(i);
      println("    " + user.getLogin());
    }
  }

  public void displayAllUsers() throws Exception {
    IUserMgr userMgr = ((IUserMgr) NamingMgr.getInstance().lookupMgr(IUserMgr.class));
    List list = userMgr.createAllUsersList(((IDomainMgr) NamingMgr.getInstance().lookupMgr(
        IDomainMgr.class)).getRootDomain());
    println("All users:");
    for (int i = 0; i < list.size(); ++i) {
      IUser user = (IUser) list.get(i);
      println("  " + user.getLogin());
      displayUserPermissions(user);
      displayUserRoles(user);
      displayUserGrantOuts(user);
      displayUserGrantIns(user);
    }
  }

  private void displayUserPermissions(IUser user) throws Exception {
    IUserMgr userMgr = ((IUserMgr) NamingMgr.getInstance().lookupMgr(IUserMgr.class));
    List list = userMgr.createPermissionsList(user);
    println("  " + user.getLogin() + " has following permissions:");
    for (int i = 0; i < list.size(); ++i) {
      IPermission perm = (IPermission) list.get(i);
      println("    " + perm.getCode());
    }
  }

  private void displayUserRoles(IUser user) throws Exception {
    IUserMgr userMgr = ((IUserMgr) NamingMgr.getInstance().lookupMgr(IUserMgr.class));
    List list = userMgr.createRolesList(user);
    println("  " + user.getLogin() + " has following roles:");
    for (int i = 0; i < list.size(); ++i) {
      IRole role = (IRole) list.get(i);
      println("    " + role.getCode());
    }
  }

  private void displayUserGrantOuts(IUser user) throws Exception {
    IUserMgr userMgr = ((IUserMgr) NamingMgr.getInstance().lookupMgr(IUserMgr.class));
    List list = userMgr.createCommissionPermissionsList(user);
    println("  " + user.getLogin() + " has following grant outs:");
    for (int i = 0; i < list.size(); ++i) {
      IPermissionCommission pc = (IPermissionCommission) list.get(i);
      println("    to " + pc.getToUser().getLogin() + " permission " + pc.getPermission().getCode()
          + " valid from " + pc.getValidFrom() + " to " + pc.getValidTo());
    }
  }

  private void displayUserGrantIns(IUser user) throws Exception {
    IUserMgr userMgr = ((IUserMgr) NamingMgr.getInstance().lookupMgr(IUserMgr.class));
    List list = userMgr.createCommissionedPermissionsList(user);
    println("  " + user.getLogin() + " has following grant ins:");
    for (int i = 0; i < list.size(); ++i) {
      IPermissionCommission pc = (IPermissionCommission) list.get(i);
      println("    from " + pc.getFromUser().getLogin() + " permission "
          + pc.getPermission().getCode() + " valid from " + pc.getValidFrom() + " to "
          + pc.getValidTo());
    }
  }

  public static void println(String s) {
    System.out.println(">>>" + s);
  }

  private Configuration getConfiguration() throws Exception {
    Configuration cfg = new Configuration();
    cfg.addClass(com.hd123.rumba.domain.Domain.class);
    cfg.addClass(com.hd123.rumba.user.RolePermission.class);
    cfg.addClass(com.hd123.rumba.user.Permission.class);
    cfg.addClass(com.hd123.rumba.user.Role.class);
    cfg.addClass(com.hd123.rumba.user.Department.class);
    cfg.addClass(com.hd123.rumba.user.User.class);
    cfg.addClass(com.hd123.rumba.user.Profile.class);
    cfg.addClass(com.hd123.rumba.user.UserRole.class);
    cfg.addClass(com.hd123.rumba.user.UserPermission.class);
    cfg.addClass(com.hd123.rumba.user.PermissionCommission.class);
    return cfg;
  }

  public void createSchema() throws Exception {
    getConfiguration().setProperty(Environment.HBM2DDL_AUTO, "create").buildSessionFactory()
        .close();
  }

  public void createData() throws Exception {
    Session sess = HibernateSession.getSession();
    Transaction tx;

    IDomainMgr domainMgr = ((IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class));
    IDomain domain = domainMgr.createDomain(null, "root", "rootdomain");
    IUserMgr userMgr = (IUserMgr) NamingMgr.getInstance().lookupMgr(IUserMgr.class);
    tx = sess.beginTransaction();
    domainMgr.saveDomain(domain, new OperateContext(userMgr.getSysUser()), domain.getOca());
    tx.commit();
    sess.flush();

    IPermissionMgr permMgr = (IPermissionMgr) NamingMgr.getInstance().lookupMgr(
        IPermissionMgr.class);
    IPermission[] perms = new IPermission[] {
        permMgr.createPermission("user.UserView", "perm1name"),
        permMgr.createPermission("user.UserEdit", "perm1name"),
        permMgr.createPermission("user.RoleView", "perm2name"),
        permMgr.createPermission("user.RoleEdit", "perm3name"),
        permMgr.createPermission("user.PermissionView", "perm2name"),
        permMgr.createPermission("user.PermissionEdit", "perm3name") };
    tx = sess.beginTransaction();
    for (int i = 0; i < perms.length; ++i) {
      permMgr.savePermission(perms[i]);
    }
    for (int i = 0; i < 128; ++i) {
      String id = "zperm" + StringUtil.lpad(Integer.toString(i), '0', 3);
      permMgr.savePermission(permMgr.createPermission(id, id));
    }
    tx.commit();
    sess.flush();

    IRoleMgr roleMgr = (IRoleMgr) NamingMgr.getInstance().lookupMgr(IRoleMgr.class);
    IRole[] roles = new IRole[] {
        roleMgr.createRole(domain, "Admin", "role1name"),
        roleMgr.createRole(domain, "User", "role1name") };
    tx = sess.beginTransaction();
    for (int i = 0; i < roles.length; ++i) {
      roleMgr.saveRole(roles[i], new OperateContext(userMgr.getSysUser()));
    }
    for (int i = 0; i < 128; ++i) {
      String id = "zrole" + StringUtil.lpad(Integer.toString(i), '0', 3);
      IRole role = roleMgr.createRole(domain, id, id);
      roleMgr.saveRole(role, new OperateContext(userMgr.getSysUser()));
    }
    tx.commit();
    tx = sess.beginTransaction();
    for (int i = 0; i < perms.length; ++i) {
      roleMgr.assignPermissionToRole(perms[i], roles[0], new OperateContext(userMgr.getSysUser()));
    }
    tx.commit();

    IUser[] users = new IUser[] {
        userMgr.createUser(domain, "admin"), userMgr.createUser(domain, "user") };
    tx = sess.beginTransaction();
    for (int i = 0; i < users.length; ++i) {
      userMgr.saveUser(users[i], new OperateContext(userMgr.getSysUser()));
    }
    for (int i = 0; i < 128; ++i) {
      String id = "zuser" + StringUtil.lpad(Integer.toString(i), '0', 3);
      IUser user = userMgr.createUser(domain, id);
      user.setName(id);
      userMgr.saveUser(user, new OperateContext(userMgr.getSysUser()));
    }
    tx.commit();

    tx = sess.beginTransaction();
    userMgr.assignRoleToUser(roles[0], users[0], new OperateContext(userMgr.getSysUser()));
    userMgr.assignRoleToUser(roles[1], users[1], new OperateContext(userMgr.getSysUser()));
    tx.commit();

    IDepartmentMgr deptMgr = DepartmentMgr.getInstance();
    IDepartment[] depts = new IDepartment[] {
        deptMgr.createDepartment(domain, "1", "第一部门"),
        deptMgr.createDepartment(domain, "2", "第二部门"),
        deptMgr.createDepartment(domain, "3", "第三部门"),
        deptMgr.createDepartment(domain, "4", "第四部门"),
        deptMgr.createDepartment(domain, "5", "第五部门") };
    tx = sess.beginTransaction();
    for (int i = 0; i < depts.length; ++i) {
      deptMgr.saveDepartment(depts[i]);
    }
    for (int i = 0; i < 128; ++i) {
      String id = "zuser" + StringUtil.lpad(Integer.toString(i), '0', 3);
      IDepartment dept = deptMgr.createDepartment(domain, id, id);
      deptMgr.saveDepartment(dept);
    }
    tx.commit();
    sess.flush();

    sess.flush();
    HibernateSession.closeSession();
    displayAllPermRoleUser("createData");
  }

  public void removePermission(String permId) throws Exception {
    Session sess = HibernateSession.getSession();
    Transaction tx;
    IPermissionMgr permMgr = (IPermissionMgr) NamingMgr.getInstance().lookupMgr(
        IPermissionMgr.class);
    IPermission perm = permMgr.getPermissionByCode(permId);

    println("Removing permision " + permId + "...");

    tx = sess.beginTransaction();
    permMgr.removePermission(perm);
    tx.commit();

    println(permId + " has been removed");

    HibernateSession.closeSession();
    displayAllPermRoleUser("");
  }

  public void removeRole(String roleId) throws Exception {
    IDomain domain = ((IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class))
        .getRootDomain();
    IRoleMgr roleMgr = (IRoleMgr) NamingMgr.getInstance().lookupMgr(IRoleMgr.class);
    IRole role = roleMgr.getRoleByCode(domain, roleId);
    println("Removing role " + roleId);
    Transaction tx = HibernateSession.getSession().beginTransaction();
    IUserMgr userMgr = (IUserMgr) NamingMgr.getInstance().lookupMgr(IUserMgr.class);
    roleMgr.removeRole(role, new OperateContext(userMgr.getSysUser()));
    tx.commit();
    println(roleId + " has been removed");
    displayAllPermRoleUser("");
  }

  public void removePermissionFromRole(String permId, String roleId) throws Exception {

    Session sess = HibernateSession.getSession();
    Transaction tx;
    IDomainMgr domainMgr = ((IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class));
    IRoleMgr roleMgr = (IRoleMgr) NamingMgr.getInstance().lookupMgr(IRoleMgr.class);
    IPermissionMgr permMgr = (IPermissionMgr) NamingMgr.getInstance().lookupMgr(
        IPermissionMgr.class);
    IDomain domain = domainMgr.getRootDomain();
    IRole role = roleMgr.getRoleByCode(domain, roleId);
    IPermission perm = permMgr.getPermissionByCode(permId);

    println("Removing " + permId + " from " + roleId + "...");

    IUserMgr userMgr = (IUserMgr) NamingMgr.getInstance().lookupMgr(IUserMgr.class);
    tx = sess.beginTransaction();
    roleMgr.removePermissionFromRole(perm, role, new OperateContext(userMgr.getSysUser()));
    tx.commit();

    println(permId + " has been removed from " + roleId);
    displayAllPermRoleUser("");
    HibernateSession.closeSession();
  }

  public void removeUser(String userLogin) throws Exception {
    IDomain domain = ((IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class))
        .getRootDomain();
    IUserMgr userMgr = ((IUserMgr) NamingMgr.getInstance().lookupMgr(IUserMgr.class));
    IUser user = userMgr.getUserByLogin(domain, userLogin);
    println("Removing user " + userLogin);
    Transaction tx = HibernateSession.getSession().beginTransaction();
    userMgr.removeUser(user);
    tx.commit();
    println(userLogin + " has been removed");
    displayAllPermRoleUser("");
  }

  public void removePermissionFromUser(String permId, String userLogin) throws Exception {

    Session sess = HibernateSession.getSession();
    Transaction tx;
    IDomainMgr domainMgr = ((IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class));
    IUserMgr userMgr = ((IUserMgr) NamingMgr.getInstance().lookupMgr(IUserMgr.class));
    IPermissionMgr permMgr = (IPermissionMgr) NamingMgr.getInstance().lookupMgr(
        IPermissionMgr.class);
    IDomain domain = domainMgr.getRootDomain();
    IUser user = userMgr.getUserByLogin(domain, userLogin);
    IPermission perm = permMgr.getPermissionByCode(permId);

    println("Removing " + permId + " from " + userLogin + "...");

    tx = sess.beginTransaction();
    userMgr.removePermissionFromUser(perm, user, new OperateContext(userMgr.getSysUser()));
    tx.commit();

    println(permId + " has been removed from " + userLogin);
    displayAllPermRoleUser("");
    HibernateSession.closeSession();
  }

  public void removeRoleFromUser(String roleId, String userLogin) throws Exception {

    Session sess = HibernateSession.getSession();
    Transaction tx;
    IDomainMgr domainMgr = ((IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class));
    IUserMgr userMgr = ((IUserMgr) NamingMgr.getInstance().lookupMgr(IUserMgr.class));
    IRoleMgr roleMgr = (IRoleMgr) NamingMgr.getInstance().lookupMgr(IRoleMgr.class);
    IDomain domain = domainMgr.getRootDomain();
    IUser user = userMgr.getUserByLogin(domain, userLogin);
    IRole role = roleMgr.getRoleByCode(domain, roleId);

    println("Removing " + roleId + " from " + userLogin + "...");

    tx = sess.beginTransaction();
    userMgr.removeRoleFromUser(role, user, new OperateContext(userMgr.getSysUser()));
    tx.commit();

    println(roleId + " has been removed from " + userLogin);
    displayAllPermRoleUser("");
    HibernateSession.closeSession();
  }

  public void hasPermission(String userLogin, String permId) throws Exception {
    IDomainMgr domainMgr = ((IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class));
    IDomain domain = domainMgr.getRootDomain();
    IUserMgr userMgr = ((IUserMgr) NamingMgr.getInstance().lookupMgr(IUserMgr.class));
    IUser user = userMgr.getUserByLogin(domain, userLogin);
    String s = user.hasPermission(permId) ? "HAS" : "HAS NO";
    println(userLogin + " " + s + " permission " + permId);
  }

  public void grantPermission(String fromUserLogin, String toUserLogin, String permId)
      throws Exception {
    Session sess = HibernateSession.getSession();
    Transaction tx;

    println("Granting permission " + permId + " from user " + fromUserLogin + " to user "
        + toUserLogin + "...");
    IDomainMgr domainMgr = ((IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class));
    IDomain domain = domainMgr.getRootDomain();
    IUserMgr userMgr = ((IUserMgr) NamingMgr.getInstance().lookupMgr(IUserMgr.class));
    IUser fromUser = userMgr.getUserByLogin(domain, fromUserLogin);
    IUser toUser = userMgr.getUserByLogin(domain, toUserLogin);
    IPermissionMgr permMgr = (IPermissionMgr) NamingMgr.getInstance().lookupMgr(
        IPermissionMgr.class);
    IPermission perm = permMgr.getPermissionByCode(permId);
    Calendar c = new GregorianCalendar();
    c.setTime(new Date());
    c.add(Calendar.DATE, -1);
    Date df = c.getTime();
    c.add(Calendar.DATE, 2);
    Date dt = c.getTime();

    tx = sess.beginTransaction();
    userMgr.grantPermission(fromUser, toUser, df, dt, perm);
    tx.commit();

    println("granted");
    displayAllPermRoleUser("");
    HibernateSession.closeSession();
  }

  public void revokePermission(String fromUserLogin, String toUserLogin, String permId)
      throws Exception {
    Session sess = HibernateSession.getSession();
    Transaction tx;
    println("Revoking permission " + permId + " from user " + fromUserLogin + " to user "
        + toUserLogin + "...");
    IDomainMgr domainMgr = ((IDomainMgr) NamingMgr.getInstance().lookupMgr(IDomainMgr.class));
    IDomain domain = domainMgr.getRootDomain();
    IUserMgr userMgr = ((IUserMgr) NamingMgr.getInstance().lookupMgr(IUserMgr.class));
    IUser fromUser = userMgr.getUserByLogin(domain, fromUserLogin);
    IUser toUser = userMgr.getUserByLogin(domain, toUserLogin);
    IPermissionMgr permMgr = (IPermissionMgr) NamingMgr.getInstance().lookupMgr(
        IPermissionMgr.class);
    IPermission perm = permMgr.getPermissionByCode(permId);

    tx = sess.beginTransaction();
    userMgr.revokePermission(fromUser, toUser, perm);
    tx.commit();
    println("revoked.");
    displayAllPermRoleUser("");
    HibernateSession.closeSession();
  }
}
